<template>
  <v-container class="case-box my-6" style="max-width: 1500px">
    <el-button
      @click="handleBack"
      class="ml-5 text-white d-flex align-center back-button"
      style="z-index: 1"
      type="text"
    >
      <div class="d-flex align-center">
        <img src="@/static/img/icon/back.png" class="mr-1" style="width: 20px" />
        返回
      </div>
    </el-button>

    <div class="content mt-10">
      <div class="box">
        <div class="d-flex align-center flex-column">
          <div class="img">
            <img class="bc" src="@/static/img/layout/bg_openbox.png" />
            <div class="item-img">
              <img
                :src="`${BASE_URL}/${boxData.img}`"
                class="item-img"
                style="width: 100%"
                v-if="boxData.img"
              />
            </div>
          </div>

          <div style="z-index: 1" class="text-center">
            <h3 style="margin: 1.5rem 0px 0.5rem">{{ boxData.name }}</h3>
            <h4
              style="
                display: flex;
                align-items: center;
                justify-content: center;
                color: #f2a046;
                font-size: 1.1rem;
              "
            >
              <!--<span>{{ boxPrice }}</span>-->
              <span style="margin-right: 3px;font-size: 1.2rem;height: 1rem;line-height: 1.18rem;">0</span>
              <img style="width: 1.1rem;height: 1.1rem;" src="@/static/img/icon/coin.png" />
            </h4>
          </div>
          <el-button
            class="btn"
            @click="openBox"
            :disabled="disabled || !boxSkinData.list.length"
            :loading="disabled"
            style="z-index: 10;margin-top:20px"
          >
            {{
              opening ? "开箱中" : buttonDisable ? "正在处理" : "开箱"
            }}
          </el-button>
        </div>

        <div class="switch-box">
          <el-switch :disabled="disabled" v-model="closeAudio" active-color="#655AAA"></el-switch>
          <span>关闭声音</span>
          <el-switch
            :model-value="closeAnimation"
            active-color="#655AAA"
            :disabled="disabled"
            @change="onAnimationSwitchChange"
          ></el-switch>
          <span>关闭动画</span>
          <!-- <div class="btn-l">
            <span>查看最近掉落</span>
          </div>-->
        </div>
        <h4
          class="open-tip"
          style="color: rgb(88, 96, 91)"
        >本网站所有活动均为为增加趣味性所设的休闲娱乐活动，请勿沉迷；禁止利用互动活动进行赌博/欺诈/作弊/刷积分等违法违规行为，若有发现，我们将取消您的活动参与资格</h4>
        <div class="switch">
          <p>
            购买
            <img v-if="boxData.img" :src="`${BASE_URL}/${boxData.img}`" />
            可以有机会获得下面这些饰品
          </p>
        </div>

        <div v-for="(gameItem, i) in gameList" :key="i" class="lottery">
          <img class="shadow" src="@/static/img/layout/bg_yinying.png" />
          <div class="container" id="shade">
            <div class="carousel-list-box" :class="{ animation: useAnimation }">
              <div class="carousel carousel-list">
                <div
                  v-for="(item, idx) in gameItem"
                  :key="idx"
                  class="item"
                  :data-open="gameItem.length - idx === 10 ? 1 : 0"
                  :data-id="item.item_id"
                >
                  <div
                    class="item-img casebox carousel-item"
                    :style="{
                      box_sizing: 'border-box',
                      border: '2px solid ' + item.rarity_color,
                    }"
                  >
                    <img :src="item.image_url" />
                    <p>{{ item.item_name }}</p>
                  </div>
                </div>
              </div>
            </div>
          </div>
          <span class="line">
            <div class="line-bar"></div>
          </span>
        </div>
        <div class="lottery-data">
          <div class="container">
            <v-row>
              <v-col cols="12" >
                <div class="tips">
                  <div style="flex: 1;">以下为礼包中所能抽到的 CSGO 饰品</div>
                  <div style="cursor: pointer;display: flex;align-items: center" @click="handleToHistory">
                    <img src="@/static/img/battle/icon-history.png" style="width: 30px;margin-right: 5px"/>
                    开箱记录
                  </div>
                </div>
              </v-col>
            </v-row>
            <v-row>
              <v-col v-for="item in boxSkinData?.list" :key="item.id" cols="6" md="2" sm="3">
                <div class="item" style="height: 100%">
                  <div class="bac-icon">
                    <div
                      class="bac"
                      :style="{
                        'box-shadow': item.rarity_color + ' 0px 0px 60px 60px',
                      }"
                    ></div>
                  </div>
                  <div class="item-img">
                    <img :src="item.image_url" />
                  </div>

                  <div>
                    <p class="item-tag">{{ item.exterior_name }}</p>
                    <p class="item-name">{{ item.item_name }}</p>
                    <p class="item-rate">概率：{{ (item.show_probability * 100).toFixed(3) }}%</p>
                    <p class="item-price">{{ item.price }} T币</p>
                  </div>
                </div>
              </v-col>
            </v-row>
          </div>
        </div>
      </div>
    </div>

    <audio ref="lottery-audio" src="/media/opening-sound.mp3" style="display: none"></audio>

    <open-result-dialog
      v-model="openBoxDialog"
      :list-data="openedData"
      @sell="sell"
      @sell-all="sellAll"
      @close="openBoxDialog = false"
    ></open-result-dialog>
  </v-container>
</template>

<script lang="ts">
import { computed, defineComponent, reactive, toRaw, toRefs } from "vue";
import BoxService from "@/services/BoxService";
import { useRouter } from "vue-router";
import { BackpackService } from "@/services/BackpackService";
import { store, useStore } from "@/store";
import { OpenBoxResult, SkinItem } from "@/types/box";
import OpenResultDialog from "./components/OpenResultDialog.vue";
const music = new Audio("/media/opening-sound.mp3");

export default defineComponent({
  name: "CaseBox",

  setup() {
    const router = useRouter();
    const openedData: OpenBoxResult[] = [];
    const boxSkinData: {
      list: SkinItem[];
      total: number;
    } = {
      list: [],
      total: 0,
    };
    const gameList: SkinItem[][] = [[]];
    const closeAnimation = computed(() => store.getters.disableOpenBoxAnimation)

    const state = reactive({
      openBoxNum: 1,
      closeAudio: false,
      buttonDisable: false,
      boxData: {},
      ID: router.currentRoute.value.params.id,
      boxID: router.currentRoute.value.params.box_id,
      openBoxDialog: false,
      openedData: openedData,
      boxSkinData,
      num: 0,
      groupCount: 0,
      useAnimation: false,
      opening: false,
      defaultGroupCount: 0,
      animationGroupCount: 0,
      gameList,
      isShowOpenResultDialog: true,
    });

    function shuffle(arr) {
      var tmp,
        cur,
        top = arr.length;
      if (top)
        while (--top) {
          cur = Math.floor(Math.random() * (top + 1));
          tmp = arr[cur];
          arr[cur] = arr[top];
          arr[top] = tmp;
        }
      return arr;
    }

    const boxSkinList = computed(() => {
      let list = toRaw(state.boxSkinData.list);
      return JSON.parse(JSON.stringify(list));
    });

    const boxPrice = computed(() => {
      return state.boxData.price
        ? (state.boxData.price * state.openBoxNum).toFixed(2)
        : "";
    });
    function handleToHistory() {
      router.push({
        path: '/welfatebox/history',
        query: {
          box_id: state.boxID
        }
      })
    }
    return {
      ...toRefs(state),
      shuffle,
      boxSkinList,
      boxPrice,
      store: useStore(),
      router,
      closeAnimation,
      handleToHistory
    };
  },

  methods: {
    getBoxAccessories() {
      BoxService.boxSkin({
        box_id: this.boxID,
        page_size: 400,
        sort: "price",
        order: "desc",
      }).then((response) => {
        this.boxSkinData = response.data.data;
        this.generatorSkinGroupData();
        this.changeGameList();
      });
    },

    // 根据饰品概率填充数据
    generatorSkinGroupData(openItemId?: string) {
      const { list } = this.boxSkinData;

      if (!list.length) {
        console.error("没有饰品数据!");
        return [];
      }

      const ret: SkinItem[] = [];

      for (let i = 0; i < this.groupCount; i++) {
        ret.push(this.randomSkin());
      }

      if (openItemId) {
        // 末尾追入开奖饰品
        const result = list.find((item) => item.item_id === openItemId);
        if (result) {
          ret[this.groupCount - 10] = result;
        } else {
          console.error("没有找到开奖饰品!", openItemId, list);
        }
      }

      return ret;
    },

    randomSkin() {
      // 生成一个[0+, 100]的随机数
      let n = Math.random() * 100;

      const { list } = this.boxSkinData;

      let start = 0;

      // 排个序
      // 过个滤
      const _list = list.slice().sort((a, b) => a.show_probability - b.show_probability);

      for (let i = 0; i < _list.length; i++) {
        const skin = _list[i];
        const { show_probability } = skin;
        // console.log('start', start, 'end', show_probability + start, 'show_probability', skin.show_probability, 'n', n);
        if (n >= start && n <= (show_probability * 100) + start) {
          // console.log("hit!", n);
          return skin;
        }
        start += show_probability * 100;
      }

      // 未命中任何项，返回一个兜底
      // 开奖率最高的
      console.log("Default!", n, _list);
      return _list.slice(-1)[0];
    },

    resetGroupCount() {
      this.groupCount = this.defaultGroupCount;
    },

    setGroupCount() {
      this.groupCount = this.animationGroupCount;
    },

    setDefaultGroupCount() {
      this.animationGroupCount = 100;
      return new Promise((resolve) => {
        const lotteryBox = document.querySelector(".lottery");
        if (!lotteryBox) {
          resolve(this.setDefaultGroupCount());
          return;
        }
        this.defaultGroupCount = Math.max(
          Math.ceil(lotteryBox.clientWidth / 146),
          8
        );
        resolve(true);
      });
    },

    async openBox() {
      if (!this.userInfo) {
        this.$notify.warning("请先登录");
        return;
      }

      if (this.buttonDisable || this.opening) return;

      this.resetBoxPosition();
      await this.sleep(20);
      this.useAnimation = true;
      this.buttonDisable = true;
      this.num = this.boxSkinData.total;


      await BoxService.unpackRechargeWelfareBox({
        id: parseInt(this.ID),
      })
        .then((res) => {
          this.openedData = this.processOpenedData([res.data.data]);
          this.opening = true;
          this.setGroupCount();
          this.changeGameList(false);
          const that = this;
          let hasValue;
          const setValue = () => {
            if (!hasValue) {
              hasValue = true;
              this.animation();
              setTimeout(() => {
                onOpen();
              }, this.loadingTime);
            }
          }

          this.$nextTick(() => {
            if (!this.closeAnimation) {
              if (!this.closeAudio) {
                music.currentTime = 0;
                music.play();
                music.onplay = setValue;
                setTimeout(setValue, 1000);
              } else {
                setValue();
              }
            } else {
              onOpen();
            }
          });

          function onOpen() {
            music.pause();
            that.openBoxDialog = true;
            that.buttonDisable = false;
            that.useAnimation = false;
            that.opening = false;
          }
        })
        .finally(() => {
          this.buttonDisable = false;
        });

      await this.getUserInfo();
    },

    // 补充字段
    // rarity_color
    processOpenedData(data: OpenBoxResult[]) {
      return data.map((item) => {
        const result = this.boxSkinData.list.find(
          (skin) => skin.item_id === item.item_id
        );
        const rarity_color = result
          ? result.rarity_color
          : item.rarity_color || "";
        return {
          ...item,
          rarity_color,
        };
      });
    },

    animation() {
      const ch = document.querySelector("#shade")!.clientWidth;
      const carouselBoxs = document.querySelectorAll(".carousel-list-box");

      setTimeout(() => {
        carouselBoxs.forEach((box, index) => {
          const targetElement = box.querySelector(`[data-open="1"]`);

          if (targetElement) {
            const targetWidth = targetElement.clientWidth;
            const n = Math.min(Math.max(Math.random(), 0.2), 0.8);

            box.style.left =
              -(
                targetElement.offsetLeft -
                ch / 2 +
                targetWidth -
                targetWidth * n
              ) + "px";
          } else {
            console.error("animation: 没有找到饰品所在位置");
          }
        });
      }, 0);
    },

    resetBoxPosition() {
      const carouselBoxs = document.querySelectorAll(".carousel-list-box");
      carouselBoxs.forEach((box) => {
        box.style.left = "0px";
      });
    },

    async getBox() {
      const res = await BoxService.id({ box_id: this.boxID });
      this.boxData = res.data.data;
    },

    getUserInfo() {
      this.store.dispatch("getUserInfo");
    },

    async sell(item: OpenBoxResult) {
      const { backpack_id: id, has_sold } = item;
      if (has_sold) {
        this.$notify.warning("该饰品已出售");
        return;
      }

      await BackpackService.batchSell({ ids: [id] });
      await this.getUserInfo();
      this.$notify.success("出售成功");
      this.setSoldStatus(id);
    },

    async sellAll() {
      const ids = this.openedData
        .filter((item) => !item.has_sold)
        .map((item) => {
          return item.backpack_id;
        });

      if (!ids.length) {
        this.$notify.warning("没有可出售的饰品");
        return;
      }

      await BackpackService.batchSell({ ids: ids });
      this.getUserInfo();
      this.$notify.success("出售成功");
      this.openBoxDialog = false;

      ids.map((id) => {
        this.setSoldStatus(id);
      });
    },

    setSoldStatus(id: number) {
      const item = this.openedData.find((item) => item.backpack_id === id);
      if (!item) return false;
      item.has_sold = true;
      return true;
    },

    // 1. 切换购买数量
    // 2. 点击购买
    changeGameList(isRefresh = true) {
      const gameList: SkinItem[][] = [];
      for (let i = 0; i < this.openBoxNum; i++) {
        // 只有在填充数据时（获取开奖结果以后）才传入开奖的饰品id
        const openItemId = !isRefresh ? this.openedData[i].item_id : "";
        const groupData = this.generatorSkinGroupData(openItemId);
        if (isRefresh) {
          gameList.push(groupData);
        } else {
          const currentGroupData = this.gameList[i] || [];
          gameList.push([...currentGroupData, ...groupData]);
        }
      }

      this.gameList = gameList;
      return gameList;
    },

    handleChangeSeed() {
      (this.$refs.updateSeed as any).open();
    },

    onAnimationSwitchChange(value: boolean) {
      this.store.commit("changeOpenBoxAnimationStatus", value);
    },

    handleBack() {
      this.router.replace("/csgo");
    },

    sleep(t) {
      return new Promise((resolve) => setTimeout(resolve, t));
    },
  },

  mounted() {
    this.setDefaultGroupCount().then(() => {
      this.resetGroupCount();
      this.getBox();
      this.getBoxAccessories();
    });
  },

  computed: {
    userInfo() {
      return this.store.getters.userInfo;
    },
    disabled() {
      return this.buttonDisable || this.opening;
    },
    loadingTime() {
      return this.store.getters.loadingTime;
    },
  },

  components: {
    OpenResultDialog,
  }
});
</script>

<style lang="scss" scoped>
.case-box {
  position: relative;
  width: 100%;
  margin: 0 auto;

  .return {
    cursor: pointer;
    position: absolute;
    color: #fff;
    top: 3rem;
    font-size: 1.4rem;
    left: 6%;
    display: flex;
    align-items: center;

    div {
      padding-left: 8px;
    }
  }

  .title {
    width: 100%;
    color: #fff;
    text-align: center;
    padding-top: 3rem;
    margin-bottom: 4rem;
    font-size: 20px !important;
    font-weight: 500;
  }

  .back-button {
    top: 0;
    left: 13px;
    position: absolute;
  }

  .content {
    .box {
      .img {
        position: relative;
        width: 40rem;
        // height: 40rem;
        display: -webkit-box;
        display: -ms-flexbox;
        display: flex;
        align-items: center;
        justify-content: center;

        .bc {
          position: absolute;
          width: 100%;
          z-index: 0;
        }

        .item-img {
          // top: 1.2rem;
          display: grid;
          justify-items: center;
          width: 20rem;
          position: relative;
          z-index: 1;
        }
      }

      .text {
        text-align: center;
      }

      .btn {
        width: 10.6rem;
        height: 3.4rem;
        background-color: #8e7eed;
        color: #fff;
        border: none;
        font-size: 1.2rem;
        font-weight: 900;
      }

      .switch-box {
        width: 100%;
        margin-top: 20px;
        display: flex;
        justify-content: center;
        align-items: center;

        span {
          padding: 0 5px;
          color: #fff;
        }

        .btn-l {
          position: relative;
          left: 10px;
          padding: 6px 15px;
          background: rgb(152, 152, 152);
          cursor: pointer;

          span {
            width: 100%;
            color: rgb(255, 255, 255);
            height: 100%;
            font-size: 1.2rem;
            font-weight: 900;
          }
        }
      }

      .open-tip {
        width: 60%;
        margin: 2rem auto 0 auto;
        color: #fff;
        text-align: center;
      }

      .switch {
        display: flex;
        justify-content: center;
        margin: 2rem auto 4rem auto;

        p {
          color: rgb(140, 155, 145);
          margin: 0px 0px 0px 1.4rem;

          img {
            width: 5rem;
            position: relative;
            top: 1rem;
          }
        }
      }

      .lottery {
        position: relative;
        background: url(@/static/img/layout/bg_zhuanpan.png) center center
          no-repeat;

        width: 1566px;
        height: 258.5px;
        background-size: contain;
        margin: 0 auto 0 auto;

        .shadow {
          width: 1500px;
          position: absolute;
          z-index: 10;
          left: 32px;
          top: 35px;
          height: 190px;
        }

        .container {
          position: absolute;
          bottom: 36px;
          width: 93.2%;
          height: 185px;
          left: 50%;
          overflow: hidden;
          transform: translateX(-50%);

          .carousel {
            display: flex;

            left: 0;
            height: 100%;
            width: 100%;

            .item {
              display: flex;
              justify-content: center;
              text-align: center;

              .item-img {
                // width: 90%;
                // margin: 0 auto 0 auto;
                // flex: 1;
                width: 146px;
                height: 100%;

                img {
                  width: 90%;
                  margin-top: 10px;
                }

                p {
                  color: #fff;
                  font-size: 12px;
                  width: 86%;
                  margin: 0 auto 6px;
                }
              }
            }
          }
        }

        .line {
          position: absolute;
          height: 100%;
          bottom: 0;
          width: 23.5px;
          display: flex;
          justify-content: center;
          left: 50%;
          transform: translateX(-11px);

          .line-bar {
            width: 5px;
            height: 100%;
            background-color: #fff;
            box-shadow: 0 6px 24px 0 #ff2e05, 0 6px 24px 0 #ff2e05;
          }

          &::before,
          &::after {
            display: block;
            position: absolute;
            content: "";
            border: 10.5px solid transparent;
          }

          &::before {
            top: 0;
            border-top-color: #ff9000;
          }

          &::after {
            bottom: 0;
            border-bottom-color: #ff9000;
          }
        }
      }

      .lottery-data {
        width: 90%;
        margin: 0 auto;

        .container {
          .item {
            position: relative;
            box-sizing: border-box;
            background-color: #36363c;

            .bac-icon {
              width: 45%;
              height: 45%;
              position: absolute;
              z-index: 0;
              top: 2.4rem;
              left: 50%;
              transform: translateX(-50%);
              border-radius: 50%;

              .bac {
                position: absolute;
                top: 50%;
                left: 50%;
                transform: translate(-50%, -50%);
                width: 0px;
                height: 0px;
                border-radius: 50%;
                z-index: 0;
              }

              img {
                z-index: 1;
                position: relative;
                width: 100%;
                transform: scale(2);
                opacity: 0.8;
              }
            }

            .item-img {
              position: relative;
              z-index: 1;
              width: 100%;
              padding: 3rem 2.5rem 1rem 2.5rem;

              img {
                width: 100%;
                opacity: 1;
                transition: all 1s ease 0s;
              }
            }

            .item-tag {
              position: absolute;
              top: 0;
              left: 0;
              color: #989898;
              border-radius: 0 0 15px 0;
              font-weight: 900;
              padding: 0.325rem 0.875rem 0.325rem 0.625rem;
              font-size: 0.725rem;
              background: rgba(47,47,53,0.6);
            }

            .item-name {
              &.sub {
                color: rgb(152, 152, 152);
                margin-top: 0px;
              }

              color: #fff;
              // width: 80%;
              margin: 0 10%;
              font-weight: 600;
              text-align: center;
              margin-top: 0.2rem;
            }

            .item-rate {
              display: block;
              // width: 80%;
              // height: 2.6rem;
              color: #fff;
              margin: 0.325rem auto 0 auto;
              border-radius: 0.4rem;
              text-align: center;
              font-weight: 600;
              // line-height: 2.6rem;
              font-size: 0.95rem;
              // transform: scale(0.7);
            }

            .item-price {
              color: #fff;
              font-weight: 700;
              text-align: center;
              // font-size: 1.4rem;
              margin: 0 0 0 0;
              color: #ff7d13;
              opacity: 0;
              transition: 0.6s;
            }

            &:hover .item-price {
              opacity: 1;
            }
          }
        }
      }
      .tips {
        display: flex;
        color: #fff;
        font-size: 1.2rem;
        font-weight: 500;
        margin: 3rem 0;
        width: 100%;
      }
    }
  }
}

#shade {
  display: flex;
  align-items: center;
}

.carousel-list-box {
  display: flex;
  flex-wrap: nowrap;
  width: 100%;
  position: absolute;
  left: 0;
  top: 50%;
  transform: translateY(-50%);

  &.animation {
    transition: left 6s cubic-bezier(0, 0, 0.01, 1);
  }

  .carousel-list {
    flex: none;
  }
}

@media screen and (max-width: 768px) {
  .case-box .content .box {
    .img {
      width: 15rem;

      .bc {
        width: 200%;
      }

      .item-img {
        width: 15rem;
      }
    }

    .lottery {
      width: calc(100% + 2rem);
      height: 160px;
      background-size: cover;
      margin-left: -1rem;
      margin-right: -1rem;

      .shadow {
        max-width: 100%;
        top: 0;
        left: 0;
        right: 0;
        display: none;
      }

      .container {
        top: 50%;
        left: 0;
        transform: translateY(-50%);
        bottom: auto;
        width: 100%;
        height: 100%;

        .carousel-list-box {
          height: 100%;
          display: flex;
          align-items: center;
        }

        .carousel {
          height: 75%;

          .item {
            width: 25%;
            .carousel-item {
              // width: 90px;
              height: 100%;

              p {
                display: -webkit-box;
                -webkit-box-orient: vertical;
                -webkit-line-clamp: 2;
                overflow: hidden;
              }

              img {
                width: 86%;
              }
            }
          }
        }
      }
    }

    .open-tip {
      width: 90%;
    }

    .user-seed-detail {
      span:first-child {
        // display: none;
      }
    }
  }
}

.user-seed-content {
  word-break: break-all;
  word-wrap: break-word;
}
</style>
